package org.ourguy.mymoviesandshows.datamodel;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * A Season abstract data type containing a list of episodes
 * @author bordjukov
 */
public class Season implements IWatchable, IFavoritable, Comparable<Season> {
	
	/**
	 * List of the episodes in the season.
	 */
	private ArrayList<Episode> episodes = new ArrayList<Episode>();
	
	/**
	 * The consecutive number of the season.
	 */
	private int number;
	
	/**
	 * Indicates if the season has been favoured.
	 */
	private boolean favorite = false;
	
	/**
	 * URL of the season
	 */
	private URL url;
	
	/**
	 * Image for the season
	 */
	private ICoverArt image;
	
	/**
	 * Create a new season with only summary data.
	 * @param number Consecutive number of the season in context of the show.
	 * @deprecated See {@link SeasonInfo}
	 */
	public Season(int number){
		this.number = number;
	}
	
	/**
	 * Create a new season from a SeasonInfo object and a list of episodes.
	 * @param si The season info
	 * @param episodes the episode list
	 */
	public Season(SeasonInfo si, ArrayList<Episode> episodes) {
		this.number = si.getNumber();
		this.url = si.getURL();
		this.image = si.getImage();
		this.episodes = episodes;
	}
	
	/**
	 * 
	 * @param number
	 * @param episodes
	 */
	public Season(int number, ArrayList<Episode> episodes) {
		this.number = number;
		this.episodes = episodes;
	}
	
	/**
	 * @return The consecutive number of the season.
	 */
	public int getNumber() {
		return number;
	}

	/**
	 * @param number The consecutive number of the season to set
	 */
	public void setNumber(int number) {
		this.number = number;
	}

	/**
	 * Add an episode to the season.
	 * @param ep The episode to be added.
	 */
	public void addEpisode(Episode ep){
		episodes.add(ep);
	}
	
	/**
	 * Add an episode collection to the season.
	 * @param ep The episode to be added.
	 */
	public void addEpisode(Collection<Episode> ec){
		episodes.addAll(ec);
	}
	
	/**
	 * Remove an episode from the season
	 * @param ep The episode to be removed.
	 */
	public void removeEpisode(Episode ep){
		episodes.remove(ep);
	}
	
	/**
	 * Get episode by its consecutive number in the season
	 * @param index The consecutive number of the episode.
	 * @return The sought episode
	 */
	public Episode getEpisodeAt(int index){
		if (index < episodes.size() && index >= 0){
			return episodes.get(index);
		}
		else{
			return null;
		}
	}
	
	/**
	 * Get the number of episodes in the season.
	 * @return The number of episodes.
	 */
	public int numEpisodes(){
		return episodes.size();
	}

	/**
	 * Favorite the season. 
	 */
	public void addToFavorites() {
		favorite = true;
	}

	/**
	 * Remove the season from favourites.
	 */
	public void removeFromFavorites() {
		favorite = false;
	}

	/**
	 * Check if the season is favorite.
	 */
	public boolean isInFavorites() {
		return favorite;
	}

	/**
	 * Check if the season has been watched.
	 */
	public boolean isWatched() {
		Iterator<Episode> i = episodes.iterator();
		
		while(i.hasNext()) //Checking if all episodes have been watched.
			if(!i.next().isWatched()) return false;

		return true;
	}
	
	/**
	 * Mark each of the episodes of the season as watched.
	 */
	public void setWatched() {
		Iterator<Episode> i = episodes.iterator();
		
		while(i.hasNext()) 
			i.next().setWatched();
	}

	/**
	 * Mark each of the episodes of the season as not watched.
	 */
	public void setUnWatched() {
		Iterator<Episode> i = episodes.iterator();
		
		while(i.hasNext()) 
			i.next().setUnWatched();
	}
	
	/**
	 * @return the url
	 */
	public URL getUrl() {
		return url;
	}

	/**
	 * @param url the url to set
	 */
	public void setUrl(URL url) {
		this.url = url;
	}
	
	/**
	 * Get the cover art of the season
	 * @return
	 */
	public ICoverArt getCoverArt() {
		return image;
	}

	/**
	 * Set the cover art for the season
	 * @param url URL of the image
	 * @throws MalformedURLException
	 */
	public void setCoverArt(String url) throws MalformedURLException {
		this.image = new CoverArtFromURL(url);
	}
	
	/**
	 * Set the cover art for the season
	 * @param image
	 */
	public void setCoverArt(android.graphics.Bitmap image) {
		this.image = new CoverArtFromImage(image);
	}

	/**
	 * Get an interator of the episodes.
	 * @return
	 */
	public Iterator<Episode> iterator() {
		return episodes.iterator();
	}
	
	/**
	 * Get the episode count.
	 * @return
	 */
	public int size() {
		return episodes.size();
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + number;
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Season other = (Season) obj;
		if (number != other.number)
			return false;
		return true;
	}

	/* (non-Javadoc)
	 * @see ITitle#compareTo(ITitle)
	 */
	public int compareTo(Season another) {
		return new Integer(this.getNumber()).compareTo(another.getNumber());
	}
}
